package com.bestcem.xm.survey.export.type;

import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.survey.export.BaseTypeHandler;
import com.bestcem.xm.survey.grpc.client.dto.QstructsDto;
import org.springframework.stereotype.Component;

import java.util.*;

import static com.bestcem.xm.survey.enums.QuestionTypeEnum.QUESTION_TYPE_MATRIX_SCORE;

@Component
public class MatrixScoreHandler implements BaseTypeHandler {

    @Override
    public Map<String, String> getSelectColumnChangeDictV2(JSONObject data, String dtype) {
        List<JSONObject> items = (List<JSONObject>) data.getOrDefault("items", Collections.emptyList());
        if (!items.isEmpty()) {
            Map<String, String> column_change_dict = new HashMap();
            List<JSONObject> rows_items = (List<JSONObject>) data.getOrDefault("rows_items", Collections.emptyList());
            rows_items.forEach(row_item -> {
                items.forEach(item -> column_change_dict.put(getSelectRealcolV2(data, row_item, item), getSelectReadablecolV2(data, row_item, BaseTypeHandler.clearHtml(item.getString("title")))));
            });
            return column_change_dict;
        }
        return Collections.emptyMap();
    }

    private String getSelectRealcolV2(JSONObject data, JSONObject row, JSONObject item) {
        return String.format("%s__%s__%s", data.getString("cid"), row.get("oid"), item.get("oid"));
    }


    private String getSelectReadablecolV2(JSONObject data, JSONObject row, String title) {
        return String.format("%s__%s__%s", BaseTypeHandler.clearHtml(data.getString("title")), BaseTypeHandler.clearHtml(row.getString("title")), title);
    }

    @Override
    public Map<String, String> getOpenColumnChangeDictV2(JSONObject data) {
        Map<String, String> res = new HashMap();
        List<JSONObject> items = (List<JSONObject>) data.getOrDefault("items", Collections.emptyList());
        items.forEach(v -> {
            if (isOpenRow(v)) {
                res.put(getOpenRealcolV2(data, v, null), getOpenReadablecolV2(data, v, null));
            }
        });
        return res;
    }

    private String getOpenRealcolV2(JSONObject data, JSONObject row, JSONObject item) {
        if (Objects.isNull(item)) {
            return String.format("%s__%s__row__open", data.getString("cid"), row.getString("id"));
        }
        return String.format("%s__%s__%s__open", data.getString("cid"), row.getString("id"), item.getString("id"));
    }

    private String getOpenReadablecolV2(JSONObject data, JSONObject row, JSONObject item) {
        if (Objects.isNull(item)) {
            return String.format("%s__%s__开放", BaseTypeHandler.clearHtml(data.getString("title")), BaseTypeHandler.clearHtml(row.getString("title")));
        }
        return String.format("%s__%s__%s__开放", BaseTypeHandler.clearHtml(data.getString("title")), BaseTypeHandler.clearHtml(row.getString("title")), BaseTypeHandler.clearHtml(item.getString("title")));
    }

    @Override
    public List<String> getSelectColumnListV2(JSONObject data, String dtype) {
        List<String> column_list = new ArrayList();
        List<JSONObject> rows_items = (List<JSONObject>) data.getOrDefault("rows_items", Collections.emptyList());
        List<JSONObject> items = (List<JSONObject>) data.getOrDefault("items", Collections.emptyList());
        rows_items.forEach(v -> items.forEach(s -> column_list.add(getSelectRealcolV2(data, v, s))));
        return column_list;
    }

    @Override
    public List<String> getOpenColumnListV2(JSONObject data) {
        List<String> res = new ArrayList();
        List<JSONObject> rows_items = (List<JSONObject>) data.getOrDefault("rows_items", Collections.emptyList());
        List<JSONObject> items = (List<JSONObject>) data.getOrDefault("items", Collections.emptyList());
        rows_items.forEach(v -> {
            if (isOpenRow(v)) {
                res.add(getOpenRealcolV2(data, v, null));
            }
            items.forEach(s -> {
                if (isOpenOption(s)) {
                    res.add(getOpenRealcolV2(data, v, s));
                }
            });
        });
        return res;
    }

    @Override
    public Map<Object, Object> getSelectAnswerDictV2(JSONObject dataValue, Object answers, String dtype, Boolean score_apply_type) {
        Map<Object, Object> data = new HashMap<>();
        List<JSONObject> rows_items = (List<JSONObject>) dataValue.getOrDefault("rows_items", Collections.emptyList());
        List<JSONObject> items = (List<JSONObject>) dataValue.getOrDefault("items", Collections.emptyList());
        if (Objects.isNull(answers)) {
            rows_items.forEach(row_item -> items.forEach(item -> data.put(getSelectRealcolV2(dataValue, row_item, item), null)));
        } else {
            rows_items.forEach(row_item -> {
                ((Map<String, JSONObject>) answers).forEach((row_gid, answer) -> {
                    if (row_gid.equals(row_item.getString("gid"))) {
                        items.forEach(item -> {
                            Integer itemGid = item.getInteger("gid");
                            if (answer.containsKey(itemGid)) {
                                data.put(getSelectRealcolV2(dataValue, row_item, item), answer.get(itemGid));
                            } else if (answer.containsKey(String.format("%s_no_apply", itemGid))) {
                                String _answer = score_apply_type ? String.format("%s_no_apply", itemGid) : null;
                                data.put(getSelectRealcolV2(dataValue, row_item, item), _answer);
                            } else {
                                data.put(getSelectRealcolV2(dataValue, row_item, item), null);
                            }
                        });
                    }
                });
            });
        }
        return data;
    }

    @Override
    public Map<Object, Object> getOpenAnswerDictV2(JSONObject dataValue, Object answerValue) {
        Map<Object, Object> data = new HashMap<>();
        List<JSONObject> row_items = (List<JSONObject>) dataValue.getOrDefault("rows_items", Collections.emptyList());
        if (Objects.isNull(answerValue)) {
            row_items.forEach(row_item -> {
                if (isOpenRow(row_item)) {
                    data.put(getOpenRealcolV2(dataValue, row_item, null), null);
                }
            });
        } else {
            Map<String, Object> answers = (Map<String, Object>) answerValue;
            row_items.forEach(row_item -> {
                if (isOpenRow(row_item)) {
                    answers.forEach((row_gid, answer) -> {
                        if (row_gid.equals(String.format("%s_open", row_item.get("gid")))) {
                            data.put(getOpenRealcolV2(dataValue, row_item, null), BaseTypeHandler.clearHtml((String) answer));
                        }
                    });
                }
            });
        }
        return data;
    }


    @Override
    public List<List<String>> getVarLabelsV2(JSONObject dataValue, boolean not01, boolean need_title) {
        List<List<String>> data = new ArrayList<>();
        List<String> var_list = new ArrayList(), val_list = new ArrayList();
        List<JSONObject> items = (List<JSONObject>) dataValue.getOrDefault("items", Collections.emptyList());
        List<JSONObject> rows_items = (List<JSONObject>) dataValue.getOrDefault("rows_items", Collections.emptyList());
        rows_items.forEach(row -> items.forEach(item -> var_list.add(String.format("VARIABLE LABELS %s__%s__%s '%s'.", dataValue.get("cid"), row.get("oid"), item.get("oid"), getTitles(dataValue, row, item, false)))));
        data.add(var_list);
        data.add(val_list);
        return data;
    }

    @Override
    public List<String> getSpssCodeV2(JSONObject param, QstructsDto qstruct) {
        List<JSONObject> items = (List<JSONObject>) param.getOrDefault("items", Collections.emptyList());
        List<JSONObject> rows_items = (List<JSONObject>) param.getOrDefault("rows_items", Collections.emptyList());
        List<String> head_list = new ArrayList<>();
        rows_items.forEach(row -> {
            items.stream().forEach(item -> {
                head_list.add(String.format("%s__%s__%s", param.get("cid"), row.get("oid"), item.get("oid")));
                if (row.getBoolean("is_open") && row.getBoolean("is_open")) {
                    head_list.add(String.format("%s__%s__open", param.get("cid"), row.get("oid")));
                }
            });
        });
        return head_list;
    }

    @Override
    public String getQuestionTypeValue() {
        return QUESTION_TYPE_MATRIX_SCORE.getValue();
    }
}
